module aru_unary_clamp (
    input logic               clk,
    input logic               rst_n,
          aru_unary_cfg_if.in u_aru_cfg_if,
          aru_payload_if.in   u_aru_pld_left_if,
          aru_payload_if.out  u_aru_pld_right_if
);

    // BF16 比较函数 - 可综合
    function automatic logic bf16_greater_than(bf16_t a, bf16_t b);
        logic a_sign, b_sign;
        logic [7:0] a_exp, b_exp;
        logic [6:0] a_man, b_man;

        a_sign = a.sign;
        b_sign = b.sign;
        a_exp  = a.exp;
        b_exp  = b.exp;
        a_man  = a.mant;
        b_man  = b.mant;

        // 特殊情况: NaN (exponent全1且尾数非0)
        if ((a_exp == 8'hFF && a_man != 0) || (b_exp == 8'hFF && b_man != 0)) return 1'b0;  // NaN 比较总是 false

        // 符号不同: 正数 > 负数
        if (a_sign != b_sign) return (a_sign == 0);

        // 符号相同,比较绝对值
        if (a_sign == 0) begin  // 都是正数: 大的更大
            if (a_exp != b_exp) return (a_exp > b_exp);
            else return (a_man > b_man);
        end else begin  // 都是负数: 绝对值大的更小
            if (a_exp != b_exp) return (a_exp < b_exp);
            else return (a_man < b_man);
        end
    endfunction

    function automatic logic bf16_less_than(bf16_t a, bf16_t b);
        return bf16_greater_than(b, a);  // a < b ≡ b > a
    endfunction

    logic lst_req_in_instr;
    assign lst_req_in_instr = u_aru_pld_right_if.sdb.eom && u_aru_pld_right_if.sdb.eon;

    // cfg handshake
    logic cfg_rdy, cfg_vld;
    assign cfg_vld = ~cfg_rdy;
    always_ff @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            cfg_rdy <= 1'b1;
        end else if (cfg_rdy == 1'b0) begin
            if (u_aru_pld_right_if.vld && u_aru_pld_right_if.rdy && lst_req_in_instr) begin
                cfg_rdy <= 1'b1;
            end
        end else begin
            if (u_aru_cfg_if.vld && u_aru_cfg_if.rdy) begin
                cfg_rdy <= 1'b0;
            end
        end
    end

    aru_dat_t clamp_out;
    genvar i;
    for (i = 0; i < `P_ARU * `N0; i = i + 1) begin : gen_clamp
        always_ff @(posedge clk or negedge rst_n) begin
            if (!rst_n) begin
                clamp_out.dat[i] <= '0;
            end else begin
                // 使用 BF16 比较函数,而不是直接 > <
                if (bf16_greater_than(u_aru_pld_left_if.dat.dat[i], u_aru_cfg_if.clamp_max)) begin
                    clamp_out.dat[i] <= u_aru_cfg_if.clamp_max;
                end else if (bf16_less_than(u_aru_pld_left_if.dat.dat[i], u_aru_cfg_if.clamp_min)) begin
                    clamp_out.dat[i] <= u_aru_cfg_if.clamp_min;
                end else begin
                    clamp_out.dat[i] <= u_aru_pld_left_if.dat.dat[i];
                end
            end
        end
    end


    aru_dat_t delayed_dat;
    common_delay_line #(
        .WIDTH(`P_ARU * `N0 * $bits(bf16_t)),
        .DEPTH(1)
    ) u_data_delay_line (
        .clk  (clk),
        .rst_n(rst_n),
        .en   (u_aru_pld_right_if.rdy && cfg_vld),
        .data_in  (u_aru_pld_left_if.dat),
        .data_out (delayed_dat)
    );

    logic delayed_vld;
    common_delay_line #(
        .WIDTH(1),
        .DEPTH(1)
    ) u_valid_delay_line (
        .clk  (clk),
        .rst_n(rst_n),
        .en   (u_aru_pld_right_if.rdy && cfg_vld),
        .data_in  (u_aru_pld_left_if.vld),
        .data_out (delayed_vld)
    );

    aru_sdb_t delayed_sdb;
    common_delay_line #(
        .WIDTH($bits(aru_sdb_t)),
        .DEPTH(1)
    ) u_sdb_delay_line (
        .clk  (clk),
        .rst_n(rst_n),
        .en   (u_aru_pld_right_if.rdy && cfg_vld),
        .data_in  (u_aru_pld_left_if.sdb),
        .data_out (delayed_sdb)
    );

    // Interface assignments - use correct port names
    assign u_aru_pld_left_if.rdy  = u_aru_pld_right_if.rdy && cfg_vld;
    assign u_aru_pld_right_if.vld = delayed_vld && cfg_vld;
    assign u_aru_pld_right_if.dat = u_aru_cfg_if.en ? clamp_out : delayed_dat;
    assign u_aru_pld_right_if.sdb = delayed_sdb;



endmodule
